package com.sztz.design.buildprototype;

import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.Date;

/**
 * 深拷贝实现原型模式
 * @author yzy
 * @date 2022/8/30 19:57
 */
@Data
@Slf4j
public class DeepUser implements Cloneable,Serializable {
    private String name;
    private String code;
    private Integer age;
    private Date birth;
    @Override
    public Object clone() throws CloneNotSupportedException {
        Object object = super.clone();
        // 实现深度克隆(deep clone)
        DeepUser user = (DeepUser)object;
        user.birth = (Date) this.birth.clone();
        return object;
    }

    public static void deepPrototypePattern1() throws Exception {
        DeepUser user = new DeepUser();
        user.setName("深深");
        user.setAge(16);
        user.setCode("ShenObj");
        user.setBirth(new Date());
        //深拷贝
        DeepUser newUser = (DeepUser)user.clone();
        newUser.setAge(18);
        long time = System.currentTimeMillis()+1000;
        newUser.getBirth().setTime(time);
        log.info("prototype1 user = {}", JSONUtil.toJsonStr(user));
        log.info("prototype1 clone user = {}",JSONUtil.toJsonStr(newUser));
    }

    public static void deepPrototypePattern2() throws Exception {
        DeepUser user = new DeepUser();
        user.setName("深深");
        user.setAge(16);
        user.setCode("ShenObj");
        user.setBirth(new Date());

        //使用序列化和反序列化实现深拷贝
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream    oos = new ObjectOutputStream(bos);
        oos.writeObject(user);
        byte[] bytes = bos.toByteArray();
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream	  ois = new ObjectInputStream(bis);
        DeepUser newUser = (DeepUser)ois.readObject();
        newUser.setAge(18);
        long time = System.currentTimeMillis()+1000;
        newUser.getBirth().setTime(time);
        log.info("prototype2 user = {}", JSONUtil.toJsonStr(user));
        log.info("prototype2 clone user = {}",JSONUtil.toJsonStr(newUser));
    }

    public static void main(String[] args) throws Exception {
        deepPrototypePattern1();
        deepPrototypePattern2();
    }
}
